<template>
    <div>
        
        
    </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
/**
 * 可串联构造器
 * 在 JavaScript 中我们经常会使用可串联（Chainable/Pipeline）的函数构造一个对象，
但在 TypeScript 中，你能合理的给它赋上类型吗？

在这个挑战中，你可以使用任意你喜欢的方式实现这个类型 - Interface, Type 或 Class 都行。
你需要提供两个函数 option(key, value) 和 get()。
在 option 中你需要使用提供的 key 和 value 扩展当前的对象类型，通过 get 获取最终结果
*/

type Chainable<T = {}> = {
  option<K extends string, S>(
    key: K extends keyof T ? never : K,
    value: S,
  ): Chainable<
    // T代表历史加入的字段类型， 并上 option新加入的K才是所有的字段类型
    {
      // 核心，从原来的 T 中排除 K 属性，这样交叉后的结果就是传入的 S 属性
      [P in keyof T as P extends K ? never : P]: T[P];
    } & {
      [P in K]: S;
    }
  >;
  get(): T;
};

// declare const config: Chainable;

// const result = config
//   .option('foo', 123)
//   .option('name', 'type-challenges')
//   .option('bar', { value: 'Hello World' })
//   .get();

// 期望 result 的类型是：
interface Result {
  foo: number;
  name: string;
  bar: {
    value: string;
  };
}

// 场景案例：localstorage对象存储状态
declare let store: Chainable



let currentStore = store
.option('time', '2023-01-31')
.option('token', 'sadhqojafns2131sfjkp123')
.option('userinfo', 'liurui')
.get()




// let currentStore = ref()
</script>

<style scoped>

</style>